/*
 * serv.c
 *
 *  Created on: Mar 30, 2012
 *      Author: root
 */

#include	"unp.h"

int word_cnt(char* str);

void sig_chld(int signo){
	pid_t pid;
	int stat;

	while((pid = waitpid(-1, &stat, WNOHANG))>0)
		printf("child %d terminated\n", pid);
	return;
}

int
main(int argc, char **argv)
{
	int					listenfd, connfd;
	pid_t				childpid;
	socklen_t			clilen;
	struct sockaddr_in	cliaddr, servaddr;
	void				sig_chld(int);

	/////////////
	static char	read_buf[MAXLINE];
	static char	send_buf[MAXLINE];
	int bytecnt, tot_byte=0;
	int wordcnt, tot_word=0;
	int linecnt=0;
	/////////////////////

	listenfd = Socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(SERV_PORT);

	Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

	Listen(listenfd, LISTENQ);

	Signal(SIGCHLD, sig_chld);	//must call waitpid()
	// SIGCHLD -> sig_chld function call

	for ( ; ; ) {
		clilen = sizeof(cliaddr);
		if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
			if (errno == EINTR)
				continue;		// back to for()
			else
				err_sys("accept error");
		}

		if ((childpid = Fork()) == 0) { // child process
			Close(listenfd); // close listening socket

			do{
				bytecnt = read(connfd, read_buf, sizeof(read_buf));

				if(strcmp(read_buf,".\n")==0){
					sprintf(send_buf, "total_byte_count : %d, total_word_count : %d, total_line_count : %d\n", tot_byte, tot_word, linecnt);
					Writen(connfd, send_buf, MAXLINE);
					exit(0);
				}

				wordcnt = word_cnt(read_buf);
				bytecnt--;
				linecnt++;
				tot_byte += bytecnt;
				tot_word += wordcnt;

				sprintf(send_buf, "byte_count : %d, word_count : %d\n", bytecnt, wordcnt);

				//printf("send_buf : %s",send_buf);

				Writen(connfd, send_buf, MAXLINE);

				bzero(send_buf, MAXLINE);
				bzero(read_buf, MAXLINE);
			}while (1);

		}
		Close(connfd);			//parent closes connected socket
	}
}
